#include<stdio.h>
#include"AuroraSprite.h"
#include<assert.h>

AuroraSprite::AuroraSprite()
{
	_fp = NULL;
}

AuroraSprite::~AuroraSprite()
{
	if(_fp!=NULL)
	{
		fclose(_fp);
	}

}

void AuroraSprite::LoadAuroraSprite(char* filename)
{
	_fp = fopen(filename,"rb");

	assert( _fp != NULL);

	if(NULL == _fp)
	{
		printf("Can not open file %s \n.",filename);
		return;
	}

	//	get all file content string
	string fileContent;
	char ch = fgetc(_fp);
	while(!feof(_fp))
	{
		fileContent += ch;
		ch=fgetc(_fp);
	}

	fclose(_fp);			//	after get file content ,we should close file at once.
	_fp = NULL;

	
	//	get file head info
	vector<string> AllLines;
	StringHelper::ParseIntoArray(AllLines,fileContent,"\n");

	//	trim all text line
	vector<string> dataString;
	for(vector<string>::iterator it = AllLines.begin();it != AllLines.end();++it)
	{
		//	get header info here.
		if(StringHelper::IsInclude(*it,"size:"))
		{
			vector<string> data;
			StringHelper::ParseIntoArray(data,*it," ");

			for(size_t i=0;i<data.size();i++)
			{
				if( data[i] == "size:")
				{
					_width = StringHelper::ParseToInt(data[i+1]);
					_height = StringHelper::ParseToInt(data[i+3]);	
				}
			}

			/*_width = StringHelper::ParseToInt(data[8]);
			_height = StringHelper::ParseToInt(data[10]);	*/
		}
		
		*it = StringHelper::Trim(*it);						//	get all trimmed string vector
	}


	//	get content data
	int iLinesCount = AllLines.size();
	int offline = 0;
	for(int i = 0;i < iLinesCount;i++)
	{
		string line = AllLines[i];
		
		//	get modules data
		if(StringHelper::IsStartWith(line,"MODULES"))
		{
			offline = 2;
			string curLine = AllLines[i+offline];
			for(;StringHelper::IsStartWith(curLine,"MD");offline++,curLine = AllLines[i+offline])
			{
				vector<string> curModuleData;
				StringHelper::ParseIntoArray(curModuleData,curLine,"\t");
				
				SpriteModule curModule;
				curModule._moduleId = curModuleData[1];
				curModule._u = StringHelper::ParseToInt(curModuleData[4]);
				curModule._v = StringHelper::ParseToInt(curModuleData[5]);
				curModule._width = StringHelper::ParseToInt(curModuleData[6]);
				curModule._height = StringHelper::ParseToInt(curModuleData[7]);

				_allModules.push_back(curModule);			
	
			}
		}

		//	get frames data
		else if(StringHelper::IsStartWith(line,"FRAME"))
		{
			offline = 2;
			
			SpriteFrame curFrame;

			string data = AllLines[i+offline];
			curFrame._frameId = data;

			++offline;
			data = AllLines[i+offline];
			for(;StringHelper::IsStartWith(data,"FM");offline++,data = AllLines[i+offline])
			{
				vector<string> curFModuleData;
				StringHelper::ParseIntoArray(curFModuleData,data,"\t");

				SpriteFModule curFModule;
				curFModule._moduleId = curFModuleData[1];
				curFModule._ox = StringHelper::ParseToInt(curFModuleData[2]);
				curFModule._oy = StringHelper::ParseToInt(curFModuleData[3]);				
				curFrame._allFModules.push_back(curFModule);
			}

			_allFrames.push_back(curFrame);
		}

		//	get anims data
		else if(StringHelper::IsStartWith(line,"ANIM"))
		{
			offline = 2;

			SpriteAnim curAnim;

			string data = AllLines[i+offline];
			curAnim._animId = data;
			
			++offline;
			data = AllLines[i+offline];
			for(;StringHelper::IsStartWith(data,"AF");++offline,data = AllLines[i+offline])
			{
				vector<string> curAFrameData;
				StringHelper::ParseIntoArray(curAFrameData,data,"\t");
				
				SpriteAFrame curAFrame;
				curAFrame._frameId = curAFrameData[1];
				curAFrame._time = StringHelper::ParseToInt(curAFrameData[2]);
				curAFrame._ox =  StringHelper::ParseToInt(curAFrameData[3]);
				curAFrame._oy =  StringHelper::ParseToInt(curAFrameData[4]);
				curAnim._allAFrames.push_back(curAFrame);
			}
			_allAnims.push_back(curAnim);
		}
	}
	
	InitFrameRect();		//	init rect data info for each Sprite Frame.
}



SpriteModule AuroraSprite::GetModuleByModuleId(string moduleId)
{
	vector<SpriteModule>::iterator it;
	for(it = _allModules.begin();it!=_allModules.end();++it)
	{
		if((*it)._moduleId == moduleId)
		{
			return (*it);	//	found the target
		}	
	}
	return (*it);			//	return _allModules.end(),not found
}

/**
	After LoadAuroraSprite(), we sum per frame's rect and size.
*/
void AuroraSprite::InitFrameRect()
{
	for(vector<SpriteFrame>::iterator it = _allFrames.begin();it!=_allFrames.end();++it)
	{
		FRect frameRect(0,0,0,0);
		
		vector<SpriteFModule>::iterator itFModule = (*it)._allFModules.begin();
		for(;itFModule!=(*it)._allFModules.end();++itFModule)
		{
			SpriteModule curModule = GetModuleByModuleId((*itFModule)._moduleId);
			/*if( curModule == _allModules.end())
			{
				continue;
			}*/

			if(itFModule == (*it)._allFModules.begin())		//	the first one assign to frameRect
			{
				frameRect._left = (*itFModule)._ox;
				frameRect._top = (*itFModule)._oy;
				frameRect._right = (*itFModule)._ox + curModule._width;
				frameRect._down = (*itFModule)._oy + curModule._height;
				continue;
			}

			if((*itFModule)._ox < frameRect._left)
			{
				frameRect._left = (*itFModule)._ox;
			}
			if((*itFModule)._oy < frameRect._top)
			{
				frameRect._top = (*itFModule)._oy;
			}
			if((*itFModule)._ox + curModule._width > frameRect._right)
			{
				frameRect._right = (*itFModule)._ox + curModule._width;
			}
			if((*itFModule)._oy + curModule._height > frameRect._down)
			{
				frameRect._down = (*itFModule)._oy + curModule._height;
			}
		}

		(*it)._frameRect = frameRect;
		(*it)._frameWidth = frameRect._right - frameRect._left;
		(*it)._frameHeight = frameRect._down - frameRect._top;
	}
}

void AuroraSprite::LookFileContent() const
{
	if( NULL == _fp)
	{
		printf("_fp is NULL.\n");
		return;
	}

	rewind(_fp);				
	char ch = fgetc(_fp);
	while(ch!=EOF )
	{
		putchar(ch);
		ch = fgetc(_fp);
	}
}